<?php

namespace App\Http\Controllers;

use DB;
use Illuminate\Http\Request;
use Validator;

use Unirest\Request AS API;
use Cache;

use EasyWeChat\Foundation\Application;
use EasyWeChat\Message\News;

class Oauth2Controller extends Controller
{

    public function wechat(){
        $options = [
            "debug"  => true,
            "app_id" => env("WECHAT_APP_ID"),
            "secret" => env("WECHAT_SECRET"),
            "token"  => "timepicker",
            "aes_key"=> "QSGkeiQug1Gh9Ns6cv21LtQkPZoGwCRedxNpIZ5AIto", // 可选
            // 'log' => [
            //     'level' => 'debug',
            //     'file'  => '/share/easywechat.log',
            // ]
        ];
        $app = new Application($options);

        $server = $app->server;
        $server->setMessageHandler(function ($message) {
            $news1 = new News([
                'title'       => '欢迎使用拾光！',
                'description' => '...',
                'image'       => env("QINIU_CDN").'/img/wechat/main.png',
            ]);
            $news2 = new News([
                'title'       => '查看拾光介绍',
                'description' => '课表/图书/问答/社团/动弹',
                'url'         => 'http://timepicker.cn',
                'image'       => env("QINIU_CDN").'/img/wechat/icon_intro.png',
            ]);
            $news3 = new News([
                'title'       => '加入拾光',
                'description' => '在微信用拾光',
                'url'         => 'http://'.env("APP_URL").'/user/info',
                'image'       => env("QINIU_CDN").'/img/wechat/icon_join.png',
            ]);
            $news4 = new News([
                'title'       => '下载拾光APP',
                'description' => '体验更多功能',
                'url'         => 'http://timepicker.cn',
                'image'       => env("QINIU_CDN").'/img/wechat/icon_down.png',
            ]);
            return [$news1, $news2, $news3, $news4];
        });


        return $server->serve();
    }

    //授权页
    public function authPage(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'client_id'    => 'required|string|min:1',
                'response_type'=> 'required|string|min:1',
                'scope' => 'string|min:1',
                'state' => 'string|min:1',
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");

        //从微信获取用户信息
        if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') != false ){
            $config = [
                "debug"  => true,
                "app_id" => env("WECHAT_APP_ID"),
                "secret" => env("WECHAT_SECRET"),
                "token"  => "timepicker",
                "aes_key"=> "QSGkeiQug1Gh9Ns6cv21LtQkPZoGwCRedxNpIZ5AIto", // 可选
                'oauth' => [
                    'scopes'   => ['snsapi_userinfo'],
                    'callback' => '/oauth2/auth?'.http_build_query($input)
                ]
            ];
            $app = new Application($config);
            $oauth = $app->oauth;

            // code换user
            if(isset($_GET['code'])){
                $user = $oauth->user();
                $_SESSION['wechat_user'] = $user->toArray();
                $input["state"] = $_SESSION['state']; //防止拾光state与微信state冲突2
            }

            // 未登录
            if (empty($_SESSION['wechat_user'])) {
                $_SESSION["state"] = isset($input["state"])?$input["state"]:""; //防止拾光state与微信state冲突1
                return $oauth->redirect();
            }

            $wechatUser = $_SESSION['wechat_user'];
            
            if(empty($wechatUser["original"]["unionid"]))
                    $wechatUser["original"]["unionid"] = $wechatUser["original"]["openid"];

            $header = [
                "Host"          => "user",
                "Authorization" => "Bearer ".env("ACCESS_TOKEN")
            ];
            $userResponse = API::get(env("PTIME_API")."/user/unionid/".$wechatUser["original"]["unionid"],$header);
            if($userResponse->code==200 && !empty($userResponse->body->result) )
                $user = $userResponse->body->result;
        }

        //从客户端获取用户信息
        if(!empty($input["token"])){
            $header = [
                "Host"          => "user",
                "Authorization" => "Bearer ".env("ACCESS_TOKEN")
            ];

            $userResponse = API::get(env("PTIME_API")."/user/token/".$input["token"],$header);

            if($userResponse->code!=200 || !isset($userResponse->body->error) || $userResponse->body->error == true || $userResponse->body->result == null)
                return $this::jsonResponse(true,"","token error");
            $user = $userResponse->body->result;
        }

        //获取code
        $clientResponse = API::get(env("KONG_ADMIN")."/oauth2",[],["client_id"=>$input["client_id"]]);
        if($clientResponse->code!=200 || !isset($clientResponse->body->total) || $clientResponse->body->total == 0)
            return $this::jsonResponse(true,"","client error");

        //免授权
        if(!empty($user)){
            $authData = [
                "client_id"=> $input["client_id"],
                "response_type" => $input["response_type"],
                "token"    => $user->token,
                "scope"    => !empty($input["scope"])?$input["scope"]:"",
                "state"    => !empty($input["state"])?urlencode($input["state"]):"",
            ];
            return $this->authInner($authData);
        }
        

        return view('user/auth',[
            "client"        => $clientResponse->body,
            "client_id"     => $input["client_id"],
            "response_type" => $input["response_type"],
            "scope"         => !empty($input["scope"])?$input["scope"]:"",
            "state"         => !empty($input["state"])?urlencode($input["state"]):"",
            "user"          => !empty($user)?$user:[],
            "wechat_user"   => !empty($wechatUser)?$wechatUser:[]
        ]);
    }

    public function auth(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'client_id'    => 'required|string|min:1',
                'response_type'=> 'required|string|min:1',
                'token' => 'required|string|min:1',
                'scope' => 'string|min:1',
                'state' => 'string|min:1',
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        return $this->authInner($input);
    }


    private function authInner($input)
    {
        $header = [
            "Host"          => "user",
            "Authorization" => "Bearer ".env("ACCESS_TOKEN")
        ];

        $userResponse = API::get(env("PTIME_API")."/user/token/".$input["token"],$header);

        if($userResponse->code!=200 || !isset($userResponse->body->error) || $userResponse->body->error == true || $userResponse->body->result == null)
            return $this::jsonResponse(true,"","token error");
        
        $userId = $userResponse->body->result->id;

        API::verifyPeer(false);
        API::verifyHost(false);
        $header = ["host"=>"user"];
        $body   = [
            "client_id"     => $input["client_id"],
            "response_type" => $input["response_type"],
            "authenticated_userid" => $userId
        ];
        if(isset($input["scope"])) $body["scope"] = $input["scope"];
        $authorizeResponse = API::post(env("KONG_API")."/oauth2/authorize",$header,$body);
        if($authorizeResponse->code!=200)
            return $this::jsonResponse(true,"","authorize error");

        $redirectUri = $authorizeResponse->body->redirect_uri;
        $code = explode("code=", $redirectUri)[1];
        $code = explode("&", $code)[0];

        if(!empty($input["state"])) $redirectUri .= "&state=".$input["state"];

        Cache::put($code, $userId, 1);

        return redirect($redirectUri);
    }

    public function token(Request $request)
    {
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'client_id'     => 'required|string|min:1',
                'client_secret' => 'required|string|min:1',
                'grant_type'    => 'required|string|min:1',
                'code'          => 'required|string|min:1',
            ]
        );
        if($validator->fails())
            return $this::jsonResponse(true,$validator->messages(),"paramError");

        API::verifyPeer(false);
        API::verifyHost(false);
        $header = ["host"=>"user"];
        $body   = [
            "client_id"     => $input["client_id"],
            "client_secret" => $input["client_secret"],
            "grant_type"    => $input["grant_type"],
            "code"          => $input["code"],
        ];
        $tokenResponse = API::post(env("KONG_API")."/oauth2/token",$header,$body);
        if($tokenResponse->code!=200)
            return $this::jsonResponse(true,json_encode($tokenResponse->body),"authorize error");

        $tokenBody = $tokenResponse->body;
     
        $tokenBody->user_id = Cache::pull($input["code"]);

        return $this::jsonResponse(false,$tokenBody);
    }


}
